package com.coocaa.ops.admin.v1.auth.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.coocaa.ops.admin.base.language.CommonLanguageProperties;
import com.coocaa.ops.admin.v1.auth.sys.biz.*;
import com.coocaa.ops.admin.v1.auth.sys.model.query.SysRoleModel;
import com.coocaa.ops.admin.v1.auth.sys.service.ISysRoleService;
import com.coocaa.ops.common.core.base.model.PageResultModel;
import com.coocaa.ops.common.core.base.model.R;
import com.coocaa.ops.common.core.base.util.PageQueryUtil;
import com.coocaa.ops.common.core.biz.auth.entity.*;
import com.coocaa.ops.common.tool.date.DateUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author bijiahao
 * @date : 2019/3/12.
 * @description: 系统角色 service接口 实现
 */
@Service
public class SysRoleServiceImpl implements ISysRoleService {
    @Autowired
    private ISysRoleBiz sysRoleBiz;
    @Autowired
    private ISysRoleMenuRunBiz sysRoleMenuRunBiz;
    @Autowired
    private ISysMenuBiz sysMenuBiz;
    @Autowired
    private ISysMenuRunBiz sysMenuRunBiz;
    @Autowired
    private ISysRunBiz sysRunBiz;
    @Autowired
    private ISysUserRoleBiz sysUserRoleBiz;
    private static CommonLanguageProperties commonLanguageProperties;


    @Override
    public String getMenuAuths(Integer roleId) {
        //所有的菜单
        List<SysMenuEntity> menus = listAllMenu();
        //所有操作权限
        List<SysRunEntity> runs = listAllRun();
        //所有菜单的操作列表
        List<SysMenuRunEntity> menuRuns = sysMenuRunBiz.queryAll(null);
        //当前角色拥有的菜单权限
        List<SysRoleMenuRunEntity> roleMenuRuns = listAllRoleMenuRun(roleId);
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        sb.append(getMenusToString(menus, runs, menuRuns, roleMenuRuns, roleId, null));
        sb.append("]");
        return sb.toString().replaceAll(",\"children\":\\[]", "").replaceAll(",]", "]");
    }


    @Override
    public void updateRoleAuth(Integer roleId, List<Map<String, Integer>> menuRuns) {
        if (CollectionUtils.isNotEmpty(menuRuns)) {
            List<SysRoleMenuRunEntity> entitys = new ArrayList<>(menuRuns.size());
            for (Map<String, Integer> map : menuRuns) {
                SysRoleMenuRunEntity entity = new SysRoleMenuRunEntity();
                entity.setRoleId(roleId);
                Object o = map.get("menuId");
                Integer menuId = Integer.valueOf(o.toString());
                entity.setMenuId(menuId);
                Object m = map.get("runId");
                Integer runId = Integer.valueOf(m.toString());
                entity.setRunId(runId);
                entitys.add(entity);
            }
            sysRoleMenuRunBiz.saveBatch(roleId, entitys);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysRoleEntity entity, Integer userId) {
        if (null == entity.getId()) {
            entity.setCreator(userId);
            entity.setCreatedDate(DateUtil.getCurDate());
            sysRoleBiz.add(entity);
        } else {
            entity.setLastUpdateDate(DateUtil.getCurDate());
            entity.setModifier(userId);
            sysRoleBiz.updateById(entity);
        }
    }

    @Override
    public SysRoleEntity getDetailInfo(Integer id) {
        SysRoleEntity query = sysRoleBiz.queryById(id);
        query.setId(query.getId());
        return query;
    }

    @Override
    public Map<String, Object> getPageResult(SysRoleModel model) {
        Map<String, Object> params = PageQueryUtil.getFilterMap(model);
        PageResultModel<SysRoleEntity> pageResult = sysRoleBiz.getCommonPageList(params, false);
        return R.ok(pageResult);
    }

    /**
     * 更新排序
     *
     * @param id
     * @param seq
     */
    @Override
    public void updateSeq(Integer id, Integer seq) {
        SysRoleEntity update = new SysRoleEntity();
        update.setId(id);
        update.setSeq(seq);
        sysRoleBiz.updateById(update);
    }

    @Override
    public Map<String, Object> listUserByRoleId(Integer roleId) {
        List<SysUserEntity> list = sysRoleBiz.getMapper().listUserByRoleId(roleId);
        return R.ok(list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map deleteBatch(Integer[] ids, SysUserEntity user) {
        String result = this.deleteBatch(ids, user.getId());
        if (R.SUCCESS.equals(result)) {
            return R.ok().msg(commonLanguageProperties.getDeleteSuccess());
        } else {
            return R.fail(result);
        }
    }

    @Autowired
    public void setEnterKeyLetterArt(CommonLanguageProperties commonLanguageProperties) {
        SysRoleServiceImpl.commonLanguageProperties = commonLanguageProperties;
    }
    /*************** ===私有方法=== ********************* ===start=== ***************************************/
    /**
     * 处理批量删除
     *
     * @param ids
     * @param userId
     * @return
     */
    private String deleteBatch(Integer[] ids, Integer userId) {
        if (ArrayUtils.isNotEmpty(ids)) {
            sysRoleMenuRunBiz.getMapper().deleteBatchByRoleIds(ids);
            sysUserRoleBiz.getMapper().deleteBatchByRoleIds(ids);
            QueryWrapper<SysRoleEntity> wrapper = new QueryWrapper<>();
            wrapper.in("id", ids);
            sysRoleBiz.getMapper().delete(wrapper);
        }
        return R.SUCCESS;
    }

    /**
     * 所有的菜单
     *
     * @return
     */
    private List<SysMenuEntity> listAllMenu() {
        QueryWrapper<SysMenuEntity> queryMenu = new QueryWrapper();
        queryMenu.eq("disabled", 0);
        List<SysMenuEntity> menus = sysMenuBiz.getMapper().selectList(queryMenu);
        return menus;
    }

    /**
     * 所有操作权限
     *
     * @return
     */
    private List<SysRunEntity> listAllRun() {
        QueryWrapper<SysRunEntity> queryRun = new QueryWrapper<>();
        queryRun.orderByAsc("seq");
        //菜单操作权限
        List<SysRunEntity> runs = sysRunBiz.getMapper().selectList(queryRun);
        return runs;
    }

    /**
     * 当前角色拥有的菜单权限
     *
     * @param roleId
     * @return
     */
    private List<SysRoleMenuRunEntity> listAllRoleMenuRun(Integer roleId) {
        Map<String, Object> queryRoleMenuRun = new HashMap(1);
        queryRoleMenuRun.put("roleId", roleId);
        List<SysRoleMenuRunEntity> roleMenuRuns = sysRoleMenuRunBiz.queryAll(queryRoleMenuRun);
        return roleMenuRuns;
    }


    /**
     * 递归生成JSON格式菜单字符串
     *
     * @param menuList
     * @param menuEntity
     * @return
     */
    private String getMenusToString(List<SysMenuEntity> menuList, List<SysRunEntity> runs, List<SysMenuRunEntity> menuRuns, List<SysRoleMenuRunEntity> roleMenuRuns, Integer roleId, SysMenuEntity
            menuEntity) {
        StringBuffer sb = new StringBuffer();
        SysMenuEntity menu;
        if (menuEntity == null) {
            for (SysMenuEntity me : menuList) {
                menu = me;
                if (menu.getPid() == 0) {
                    sb.append("{\"text\":\"");
                    sb.append(me.getMenuName());
                    sb.append("\",\"menuId\":\"");
                    sb.append(me.getId());
                    sb.append("\",\"elid\":\"");
                    sb.append(me.getMenuToken());
                    sb.append("\",\"title\":\"");
                    sb.append(me.getMenuName());
                    sb.append("\",\"iconCls\":\"");
                    sb.append(me.getMenuIcon());
                    sb.append("\",\"roleId\":\"");
                    sb.append(roleId);
                    for (SysRunEntity sysRunEntity : runs) {
                        sb.append("\",\"" + sysRunEntity.getRunDesc() + "\":\"");
                        Boolean isMenuRun = false;
                        for (SysMenuRunEntity menuRunEntity : menuRuns) {
                            if (menu.getId().equals(menuRunEntity.getMenuId()) && sysRunEntity.getId().equals(menuRunEntity.getRunId())) {
                                isMenuRun = true;
                            }
                        }
                        if (isMenuRun) {
                            Boolean isRoleMenuRun = false;
                            for (SysRoleMenuRunEntity roleMenuRunEntity : roleMenuRuns) {
                                if (menu.getId().equals(roleMenuRunEntity.getMenuId()) && sysRunEntity.getId().equals(roleMenuRunEntity.getRunId())) {
                                    isRoleMenuRun = true;
                                }
                            }
                            if (isRoleMenuRun) {
                                sb.append("1");//角色有菜单操作权限
                            } else {
                                sb.append("0");//角色无菜单操作权限
                            }
                        } else {
                            sb.append("-1");//菜单没有该操作
                        }
                    }
                    sb.append("\",\"children\":[");
                    sb.append(getMenusToString(menuList, runs, menuRuns, roleMenuRuns, roleId, menu));
                    sb.append("]");
                    sb.append("},");
                }
            }
        } else {
            for (SysMenuEntity me : menuList) {
                menu = me;
                if (menuEntity.getId().equals(menu.getPid())) {
                    sb.append("{\"text\":\"");
                    sb.append(me.getMenuName());
                    sb.append("\",\"menuId\":\"");
                    sb.append(me.getId());
                    sb.append("\",\"elid\":\"");
                    sb.append(me.getMenuToken());
                    sb.append("\",\"title\":\"");
                    sb.append(me.getMenuName());
                    sb.append("\",\"iconCls\":\"");
                    sb.append(me.getMenuIcon());
                    sb.append("\",\"roleId\":\"");
                    sb.append(roleId);
                    for (SysRunEntity sysRunEntity : runs) {
                        sb.append("\",\"" + sysRunEntity.getRunDesc() + "\":\"");
                        Boolean isMenuRun = false;
                        for (SysMenuRunEntity menuRunEntity : menuRuns) {
                            if (menu.getId().equals(menuRunEntity.getMenuId()) && sysRunEntity.getId().equals(menuRunEntity.getRunId())) {
                                isMenuRun = true;
                            }
                        }
                        if (isMenuRun) {
                            Boolean isRoleMenuRun = false;
                            for (SysRoleMenuRunEntity roleMenuRunEntity : roleMenuRuns) {
                                if (menu.getId().equals(roleMenuRunEntity.getMenuId()) && sysRunEntity.getId().equals(roleMenuRunEntity.getRunId())) {
                                    isRoleMenuRun = true;
                                }
                            }
                            if (isRoleMenuRun) {
                                sb.append("1");
                            } else {
                                sb.append("0");
                            }
                        } else {
                            sb.append("-1");
                        }
                    }
                    sb.append("\",\"children\":[");
                    sb.append(getMenusToString(menuList, runs, menuRuns, roleMenuRuns, roleId, menu));
                    sb.append("]");
                    sb.append("},");
                }
            }
        }
        return sb.toString();
    }

}
